package com.youxin.admin.auth.service.Impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youxin.admin.auth.domain.MenuTree;
import com.youxin.admin.auth.domain.router.RouterMeta;
import com.youxin.admin.auth.domain.router.VueRouter;
import com.youxin.admin.auth.enums.AdminCommonConstant;
import com.youxin.admin.auth.model.Menu;
import com.youxin.admin.auth.model.User;
import com.youxin.admin.auth.service.ChatMenuService;
import com.youxin.admin.auth.service.ChatUserService;
import com.youxin.admin.auth.service.PermissionService;
import com.youxin.admin.auth.util.TreeUtil;
import com.youxin.exception.SystemException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by ace on 2019/5/23.
 */
@Service
public class PermissionServiceImpl implements PermissionService {
    @Autowired
    private ChatUserService chatUserService;
    @Autowired
    private ChatMenuService chatMenuService;

    @Override
    public Set<String> getPermissionByUsername(String username) throws SystemException {
        User user = chatUserService.getUserByUsername(username);
        List<String> result = new ArrayList<String>();
        List<Menu> elements;
        if (user.getUsername().equals("admin")) {
            elements = chatMenuService.getAllAuthorityElement();
        } else {
            elements = chatMenuService.getAuthorityMenuByUserId(user.getId());
        }
        List<Menu> menus = getMenusByUsername(username);
        element2permission(result, elements);
        menu2permission(result, menus);
        Set<String> permissions = new HashSet<>(result);
        return permissions;
    }

    private void element2permission(List<String> result, List<Menu> menus) {
        for (Menu menu : menus) {
            result.add(menu.getCode());
        }
    }

    private void menu2permission(List<String> result, List<Menu> menus) {
        for (Menu menu : menus) {
            if (!StringUtils.isEmpty(menu.getName())) {
                result.add(menu.getName());
            }
        }
    }

    private List<MenuTree> getMenuTree(List<Menu> menus, int root) {
        List<MenuTree> trees = new ArrayList<MenuTree>();
        MenuTree node = null;
        for (Menu menu : menus) {
            node = new MenuTree();
            BeanUtils.copyProperties(menu, node);
            trees.add(node);
        }
        return TreeUtil.bulid(trees, root);
    }


    private List<Menu> getMenusByUsername(String username) {
        User user = chatUserService.getUserByUsername(username);
        List<Menu> menus;
        if (user.getUsername().equals("admin")) {
            menus = chatMenuService.list(new QueryWrapper<Menu>());
        } else {
            menus = chatMenuService.getUserAuthorityMenuByUserId(user.getId());
        }
        return menus;
    }


    @Override
    public Map<String, Object> generateUserInfo(String username) throws SystemException {
        Map<String, Object> userInfo = new HashMap<>();
        Set<String> permissions = getPermissionByUsername(username);
        userInfo.put("permissions", permissions);
        List<Menu> menus;
        if (username.equals("admin")) {
            menus = chatMenuService.list(new QueryWrapper<Menu>().lambda().eq(Menu::getType, "0"));
        } else {
            User user = chatUserService.getUserByUsername(username);
            menus = chatMenuService.getUserAuthorityMenuByUserId(user.getId());
        }
        List<Menu> showMenus = menus.stream().filter(item -> item != null
                && "0".equalsIgnoreCase(item.getType()) && Boolean.FALSE.equals(item.getHidden())).collect(Collectors.toList());

        List<MenuTree> menuTrees = getMenuTree(showMenus, AdminCommonConstant.ROOT);
        userInfo.put("menuTrees", menuTrees);
        List<VueRouter<Menu>> routes = new ArrayList<>();
        menus.forEach(menu -> {
            VueRouter<Menu> route = new VueRouter<>();
            route.setId(menu.getId().toString());
            route.setParentId(menu.getParentId().toString());
            route.setIcon(menu.getIcon());
            route.setPath(menu.getPath());
            route.setComponent(menu.getComponent());
            route.setName(menu.getName());
            route.setHidden(menu.getHidden());
            route.setMeta(new RouterMeta(menu.getTitle()));
            routes.add(route);
        });
        List<VueRouter<Menu>> routers = TreeUtil.buildVueRouter(routes);
        userInfo.put("userRouter", routers);
        return userInfo;
    }
}
